package com.whfc.fmam.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.exception.BizException;
import com.whfc.common.generator.KeyGeneratorUtil;
import com.whfc.common.result.ListData;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.spring.AppContextUtil;
import com.whfc.fmam.dao.*;
import com.whfc.fmam.entity.bo.*;
import com.whfc.fmam.entity.dto.*;
import com.whfc.fmam.event.FmamWeightNoteSyncEvent;
import com.whfc.fmam.map.*;
import com.whfc.fmam.service.FmamSyncDataService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/10/16 12:01
 */
@DubboService(interfaceClass = FmamSyncDataService.class, version = "1.0.0")
public class FmamSyncDataServiceImpl implements FmamSyncDataService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private FmamSupplierMapper fmamSupplierMapper;

    @Autowired
    private FmamWarehouseMapper fmamWarehouseMapper;

    @Autowired
    private FmamMatTypeMapper fmamMatTypeMapper;

    @Autowired
    private FmamMatMapper fmamMatMapper;

    @Autowired
    private FmamUnitMapper fmamUnitMapper;

    @Autowired
    private FmamMatUnitMapper fmamMatUnitMapper;

    @Autowired
    private FmamWeighNoteMapper fmamWeighNoteMapper;

    @Autowired
    private FmamWeighNoteMatMapper fmamWeighNoteMatMapper;

    @Autowired
    private FmamWeighNoteImgMapper fmamWeighNoteImgMapper;

    @Autowired
    private SupplierMap supplierMap;

    @Autowired
    private WarehourseMap warehourseMap;

    @Autowired
    private MatTypeMap matTypeMap;

    @Autowired
    private MatMap matMap;

    @Autowired
    private WeighNoteMap weighNoteMap;

    @Autowired
    private WeighNoteMatMap weighNoteMatMap;

    @Autowired
    private UnitMap unitMap;

    @Override
    public ListData<SyncFmamSupplierDTO> getSyncSupplierDTO(FmamClientDTO fmamClientDTO, Date lastSyncTime) throws BizException {

        Integer deptId = fmamClientDTO.getDeptId();
        List<FmamSupplier> supplierList = fmamSupplierMapper.selectSyncSupplierList(deptId, lastSyncTime);
        List<SyncFmamSupplierDTO> supplierDTOList = new ArrayList<>(supplierList.size());
        for (FmamSupplier supplier : supplierList) {
            SyncFmamSupplierDTO supplierDTO = supplierMap.to(supplier);
            supplierDTOList.add(supplierDTO);
        }
        return new ListData<>(supplierDTOList);
    }

    @Override
    public ListData<SyncFmamWarehouseDTO> getSyncWarehoureDTO(FmamClientDTO fmamClientDTO, Date lastSyncTime) throws BizException {
        Integer deptId = fmamClientDTO.getDeptId();
        List<FmamWarehouse> warehouseList = fmamWarehouseMapper.selectSyncWarehouseList(deptId, lastSyncTime);
        List<SyncFmamWarehouseDTO> warehourseDTOList = new ArrayList<>(warehouseList.size());
        for (FmamWarehouse warehouse : warehouseList) {
            SyncFmamWarehouseDTO warehourseDTO = warehourseMap.to(warehouse);
            warehourseDTOList.add(warehourseDTO);
        }
        return new ListData<>(warehourseDTOList);
    }

    @Override
    public PageData<SyncFmamMatTypeDTO> getSyncMatTypeDTO(FmamClientDTO fmamClientDTO, Date lastSyncTime, Integer pageNum, Integer pageSize) throws BizException {

        PageHelper.startPage(pageNum, pageSize);
        Integer deptId = fmamClientDTO.getDeptId();
        List<FmamMatType> matTypeList = fmamMatTypeMapper.selectSyncMatTypeList(deptId, lastSyncTime);
        List<SyncFmamMatTypeDTO> matTypeDTOList = new ArrayList<>(matTypeList.size());
        PageInfo<FmamMatType> pageInfo = PageInfo.of(matTypeList);
        for (FmamMatType matType : matTypeList) {
            SyncFmamMatTypeDTO matTypeDTO = matTypeMap.to(matType);
            matTypeDTOList.add(matTypeDTO);
        }

        PageData<SyncFmamMatTypeDTO> pageData = new PageData<>();
        pageData.setList(matTypeDTOList);
        pageData.setPages(pageInfo.getPages());
        pageData.setTotal(pageInfo.getTotal());
        pageData.setPageNum(pageInfo.getPageNum());
        pageData.setPageSize(pageInfo.getPageSize());
        return pageData;
    }

    @Override
    public PageData<SyncFmamMatDTO> getSyncMatDTO(FmamClientDTO fmamClientDTO, Date lastSyncTime, Integer pageNum, Integer pageSize) throws BizException {

        PageHelper.startPage(pageNum, pageSize);
        Integer deptId = fmamClientDTO.getDeptId();
        List<FmamMat> matList = fmamMatMapper.selectSyncMatList(deptId, lastSyncTime);
        List<SyncFmamMatDTO> matDTOList = new ArrayList<>(matList.size());
        PageInfo<FmamMat> pageInfo = PageInfo.of(matList);
        for (FmamMat mat : matList) {
            SyncFmamMatDTO matDTO = matMap.to(mat);
            //查询单位转换
            List<SyncFmamMatUnitDTO> unitList = getMatUnitDTOList(mat.getId());
            matDTO.setUnitList(unitList);
            matDTOList.add(matDTO);
        }
        PageData<SyncFmamMatDTO> pageData = new PageData<>();
        pageData.setList(matDTOList);
        pageData.setPages(pageInfo.getPages());
        pageData.setTotal(pageInfo.getTotal());
        pageData.setPageNum(pageInfo.getPageNum());
        pageData.setPageSize(pageInfo.getPageSize());
        return pageData;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadWeighNote(FmamClientDTO fmamClientDTO, UploadWeighNoteDTO uploadWeighNoteDTO) throws BizException {

        Integer deptId = fmamClientDTO.getDeptId();
        Integer weighRoomId = fmamClientDTO.getWeighRoomId();
        String weighRoomCode = fmamClientDTO.getWeighRoomCode();
        String weighRoomName = fmamClientDTO.getWeighRoomName();

        List<SyncFmamWeighNoteDTO> weighNoteDTOList = uploadWeighNoteDTO.getWeighNoteList();
        List<FmamWeighNote> weighNoteList = new ArrayList<>(weighNoteDTOList.size());
        List<FmamWeighNoteMat> weighNoteMatList = new ArrayList<>();
        for (SyncFmamWeighNoteDTO weighNoteDTO : weighNoteDTOList) {
            //转换磅单数据
            long weighNoteId = KeyGeneratorUtil.genLongId();
            FmamWeighNote weighNote = weighNoteMap.from(weighNoteDTO);
            weighNote.setId(weighNoteId);
            weighNote.setDeptId(deptId);
            weighNote.setWeighRoomId(weighRoomId);
            weighNote.setWeighRoomCode(weighRoomCode);
            weighNote.setWeighRoomName(weighRoomName);
            if (ObjectUtils.isEmpty(weighNote.getConfirmWeight()) || weighNote.getConfirmWeight().isInfinite()) {
                weighNote.setConfirmWeight(0D);
            }
            //仓库
            String warehouseName = this.getWarehouseName(weighNote.getWarehouseId());
            weighNote.setWarehouseName(warehouseName);

            weighNoteList.add(weighNote);

            //转换磅单材料数据
            List<SyncFmamWeighNoteMatDTO> weighNoteMatDTOList = weighNoteDTO.getMatList();
            for (SyncFmamWeighNoteMatDTO weighNoteMatDTO : weighNoteMatDTOList) {
                long weighNoteMatId = KeyGeneratorUtil.genLongId();
                FmamWeighNoteMat weighNoteMat = weighNoteMatMap.from(weighNoteMatDTO);
                weighNoteMat.setId(weighNoteMatId);
                weighNoteMat.setWeighNoteGuid(weighNoteDTO.getGuid());
                //查询材料类别
                FmamMatType fmamMatType = fmamMatMapper.selectMatTypeByMatId(weighNoteMatDTO.getMatId());
                weighNoteMat.setMatTypeId(fmamMatType.getId());
                weighNoteMat.setMatTypeCode(fmamMatType.getFullCode());
                weighNoteMat.setMatTypeName(fmamMatType.getName());
                weighNoteMatList.add(weighNoteMat);
                //查询材料
                FmamMat fmamMat = fmamMatMapper.selectByPrimaryKey(weighNoteMatDTO.getMatId());
                weighNoteMat.setMatCode(fmamMat.getFullCode());
                weighNoteMat.setMatName(fmamMat.getName());
            }
        }
        //保存磅单
        if (weighNoteList.size() > 0) {
            fmamWeighNoteMapper.batchInsertOrUpdate(weighNoteList);
            //发送事件
            AppContextUtil.context().publishEvent(new FmamWeightNoteSyncEvent(deptId, weighNoteDTOList));
        }
        //保存磅单材料
        if (weighNoteMatList.size() > 0) {
            //先逻辑删除已有材料
            List<String> weighNoteGuidList = weighNoteMatList.stream().map(FmamWeighNoteMat::getWeighNoteGuid).collect(Collectors.toList());
            fmamWeighNoteMatMapper.batchDeleteByWeighNoteGuid(weighNoteGuidList);
            //再批量插入更新后的材料列表
            fmamWeighNoteMatMapper.batchInsert(weighNoteMatList);
        }
    }

    @Override
    public void uploadWeighNoteImage(FmamClientDTO fmamClientDTO, String guid, Integer type, Integer imgType, List<String> imgUrls, Integer genType, Date genTime) throws BizException {

        FmamWeighNote weighNote = fmamWeighNoteMapper.selectByGuid(guid);
        if (weighNote == null) {
            throw new BizException(ResultEnum.NOT_FOUND.getCode(), "磅单guid不存在");
        }
        List<FmamWeighNoteImg> weighNoteImgList = new ArrayList<>(imgUrls.size());
        for (String imgUrl : imgUrls) {
            long weighNoteImgId = KeyGeneratorUtil.genLongId();
            FmamWeighNoteImg weighNoteImg = new FmamWeighNoteImg();
            weighNoteImg.setId(weighNoteImgId);
            weighNoteImg.setWeighNoteGuid(weighNote.getGuid());
            weighNoteImg.setType(type);
            weighNoteImg.setImgType(imgType);
            weighNoteImg.setImgUrl(imgUrl);
            weighNoteImg.setGenType(genType);
            weighNoteImg.setGenTime(genTime);
            weighNoteImgList.add(weighNoteImg);
        }
        if (weighNoteImgList.size() > 0) {
            fmamWeighNoteImgMapper.deleteByWeighNoteGuidAndImgType(guid, type, imgType);
            fmamWeighNoteImgMapper.batchInsert(weighNoteImgList);
        }
    }

    @Override
    public PageData<SyncFmamWeighNoteDTO> getSyncWeighNoteDTO(FmamClientDTO fmamClientDTO, Date lastSyncTime, Integer pageNum, Integer pageSize) throws BizException {

        PageHelper.startPage(pageNum, pageSize);
        Integer deptId = fmamClientDTO.getDeptId();
        Integer weighRoomId = fmamClientDTO.getWeighRoomId();
        List<FmamWeighNote> weighNoteList = fmamWeighNoteMapper.selectSyncWeighNoteList(deptId, weighRoomId, lastSyncTime);
        List<SyncFmamWeighNoteDTO> weighNoteDTOList = new ArrayList<>(weighNoteList.size());
        PageInfo<FmamWeighNote> pageInfo = PageInfo.of(weighNoteList);
        for (FmamWeighNote weighNote : weighNoteList) {
            SyncFmamWeighNoteDTO weighNoteDTO = weighNoteMap.to(weighNote);

            //查询磅单材料
            List<SyncFmamWeighNoteMatDTO> weighNoteMatDTOList = this.getWeighNoteMatDTOList(weighNote.getGuid());
            weighNoteDTO.setMatList(weighNoteMatDTOList);

            //查询磅单图片
            List<SyncFmamWeighNoteImgDTO> weighNoteImgDTOList = this.getWeighNoteImgDTOList(weighNote.getGuid());
            weighNoteDTO.setImgList(weighNoteImgDTOList);

            weighNoteDTOList.add(weighNoteDTO);
        }

        PageData<SyncFmamWeighNoteDTO> pageData = new PageData<>();
        pageData.setList(weighNoteDTOList);
        pageData.setPages(pageInfo.getPages());
        pageData.setTotal(pageInfo.getTotal());
        pageData.setPageNum(pageInfo.getPageNum());
        pageData.setPageSize(pageInfo.getPageSize());
        return pageData;
    }

    @Override
    public ListData<SyncFmamUnitDTO> getSyncUnitDTO() throws BizException {
        List<FmamUnit> fmamUnits = fmamUnitMapper.selectAllUnitDTOList();
        List<SyncFmamUnitDTO> unitDTOList = new ArrayList<>(fmamUnits.size());
        for (FmamUnit fmamUnit : fmamUnits) {
            SyncFmamUnitDTO unitDTO = unitMap.to(fmamUnit);
            unitDTOList.add(unitDTO);
        }
        return new ListData<>(unitDTOList);
    }


    /**************private*************/

    /**
     * 查询材料转换系数
     *
     * @param matId
     * @return
     */
    private List<SyncFmamMatUnitDTO> getMatUnitDTOList(Long matId) {
        return fmamMatUnitMapper.selectMatUnitDTOListByMatId(matId);
    }

    /**
     * 查询磅单材料
     *
     * @param weighNoteGuidId
     * @return
     */
    private List<SyncFmamWeighNoteMatDTO> getWeighNoteMatDTOList(String weighNoteGuidId) {
        List<FmamWeighNoteMat> weighNoteMatList = fmamWeighNoteMatMapper.selectWeighNoteMatList(weighNoteGuidId);
        return weighNoteMatList.stream().map(mat -> weighNoteMatMap.to(mat)).collect(Collectors.toList());
    }

    /**
     * 好像磅单图片
     *
     * @param weighNoteGuidId
     * @return
     */
    private List<SyncFmamWeighNoteImgDTO> getWeighNoteImgDTOList(String weighNoteGuidId) {
        return fmamWeighNoteImgMapper.selectSyncWeighNoteImgDTOList(weighNoteGuidId);
    }

    /**
     * 查询仓库名称
     *
     * @param warehouseId
     * @return
     */
    private String getWarehouseName(Integer warehouseId) {
        if (null != warehouseId) {
            FmamWarehouse warehouse = fmamWarehouseMapper.selectByPrimaryKey(warehouseId);
            if (null != warehouse) {
                return warehouse.getName();
            }
        }
        return null;
    }


}
